package org.jeecg.modules.basic.warehouse.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.business.repertory.entity.WmsRepertory;
import org.jeecg.modules.business.repertory.mapper.WmsRepertoryMapper;
import org.jeecg.modules.business.repertory.service.IWmsRepertoryService;
import org.jeecg.modules.business.repertory.service.impl.WmsRepertoryServiceImpl;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseAreaLocation;
import org.jeecg.modules.basic.warehouse.mapper.WmsBasicWarehouseAreaLocationMapper;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaLocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouse;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @Description: 仓库-库区-库位
 * @Author: jeecg-boot
 * @Date: 2023-08-09
 * @Version: V1.0
 */
@Service
public class WmsBasicWarehouseAreaLocationServiceImpl extends ServiceImpl<WmsBasicWarehouseAreaLocationMapper, WmsBasicWarehouseAreaLocation> implements IWmsBasicWarehouseAreaLocationService {

    @Resource
    private WmsRepertoryMapper wmsRepertoryMapper;
    @Autowired
    private IWmsBasicWarehouseAreaService iWmsBasicWarehouseAreaService;
    @Autowired
    private IWmsBasicWarehouseService iWmsBasicWarehouseService;

    private final String used = "1";
    private final String unused = "0";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveByCheck(WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation) {
        if (ObjectUtil.isEmpty(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())) {
            throw new JeecgBootException("所选库位没有绑定库区id！");
        }
        List<WmsBasicWarehouseAreaLocation> nameList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                .eq(WmsBasicWarehouseAreaLocation::getName, wmsBasicWarehouseAreaLocation.getName()));
        if (ObjectUtil.isNotEmpty(nameList)) {
            throw new JeecgBootException("库位名称重复！");
        }
        List<WmsBasicWarehouseAreaLocation> codeList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                .eq(WmsBasicWarehouseAreaLocation::getCode, wmsBasicWarehouseAreaLocation.getCode()));
        if (ObjectUtil.isNotEmpty(codeList)) {
            throw new JeecgBootException("库位编码重复！");
        }
        // 更新基准点
        this.updateDatum(wmsBasicWarehouseAreaLocation);
        this.save(wmsBasicWarehouseAreaLocation);
        // 更新对应库区和仓库的容量值
        this.updateWarehouseAndAreaCapacity(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId());

        //添加库位后校验本库区是否已开启库位管理
        WmsBasicWarehouseArea area = iWmsBasicWarehouseAreaService.getById(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId());
        if (unused.equals(area.getIsUseLocation())) {
            area.setIsUseLocation(used);
            iWmsBasicWarehouseAreaService.updateById(area);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByCheck(WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation) {
        WmsBasicWarehouseAreaLocation originStoreLocation = this.getById(wmsBasicWarehouseAreaLocation.getId());
        WmsBasicWarehouseArea originArea = iWmsBasicWarehouseAreaService.getById(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId());
        if (ObjectUtil.isEmpty(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())) {
            throw new JeecgBootException("所选库位没有绑定库区id！");
        }
        List<WmsBasicWarehouseAreaLocation> nameList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                .eq(WmsBasicWarehouseAreaLocation::getName, wmsBasicWarehouseAreaLocation.getName())
                .ne(WmsBasicWarehouseAreaLocation::getId, wmsBasicWarehouseAreaLocation.getId()));
        if (ObjectUtil.isNotEmpty(nameList)) {
            throw new JeecgBootException("库位名称重复！");
        }
        List<WmsBasicWarehouseAreaLocation> codeList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                .eq(WmsBasicWarehouseAreaLocation::getCode, wmsBasicWarehouseAreaLocation.getCode())
                .ne(WmsBasicWarehouseAreaLocation::getId, wmsBasicWarehouseAreaLocation.getId()));
        if (ObjectUtil.isNotEmpty(codeList)) {
            throw new JeecgBootException("库位编码重复！");
        }
        if ("0".equals(wmsBasicWarehouseAreaLocation.getStatus())) {
            List<WmsRepertory> list = wmsRepertoryMapper.selectList(new LambdaQueryWrapper<WmsRepertory>().eq(WmsRepertory::getWmsBasicWarehouseAreaLocationId, wmsBasicWarehouseAreaLocation.getId()));
            if (ObjectUtil.isNotEmpty(list)) {
                throw new JeecgBootException("该库位有库存物料，不可禁用！");
            }
        }
        // 更新基准点
        this.updateDatum(wmsBasicWarehouseAreaLocation);
        this.updateById(wmsBasicWarehouseAreaLocation);
        this.update(new LambdaUpdateWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseId())
                .set(WmsBasicWarehouseAreaLocation::getMaxCapacity, wmsBasicWarehouseAreaLocation.getMaxCapacity())
                .set(WmsBasicWarehouseAreaLocation::getWarningCapacity, wmsBasicWarehouseAreaLocation.getWarningCapacity()));
        // 更新对应库区和仓库的容量值
        this.updateWarehouseAndAreaCapacity(wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId());
    }

    @Override
    public void removeByCheck(String id) {
        WmsBasicWarehouseAreaLocation location = this.getById(id);
        WmsBasicWarehouseArea area = iWmsBasicWarehouseAreaService.getById(location.getWmsBasicWarehouseAreaId());
        this.removeById(id);
        //删除库位后校验本库区是否启用库位管理
        List<WmsBasicWarehouseAreaLocation> list = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>().eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, area.getId()));
        if (ObjectUtil.isEmpty(list)) {
            if (used.equals(area.getIsUseLocation())) {
                area.setIsUseLocation(unused);
                iWmsBasicWarehouseAreaService.updateById(area);
            }
        }else {
            if (unused.equals(area.getIsUseLocation())) {
                area.setIsUseLocation(used);
                iWmsBasicWarehouseAreaService.updateById(area);
            }
        }
    }

    /**
     * 更新对应库区和仓库的容量值
     * @param areaId
     */
    private void updateWarehouseAndAreaCapacity(String areaId) {
        //更新对应库区的值
        List<WmsBasicWarehouseAreaLocation> list = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, areaId)
        );
        WmsBasicWarehouseArea warehouseArea = iWmsBasicWarehouseAreaService.getById(areaId);
        warehouseArea.setMaxCapacity(list.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacity())).map(WmsBasicWarehouseAreaLocation::getMaxCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouseArea.setWarningCapacity(list.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacity())).map(WmsBasicWarehouseAreaLocation::getWarningCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouseArea.setMinCapacity(list.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacity())).map(WmsBasicWarehouseAreaLocation::getMinCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouseArea.setMaxCapacityAssist(list.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacityAssist())).map(WmsBasicWarehouseAreaLocation::getMaxCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouseArea.setWarningCapacityAssist(list.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacityAssist())).map(WmsBasicWarehouseAreaLocation::getWarningCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouseArea.setMinCapacityAssist(list.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacityAssist())).map(WmsBasicWarehouseAreaLocation::getMinCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        iWmsBasicWarehouseAreaService.updateById(warehouseArea);
        //更新对应仓库的值
        List<WmsBasicWarehouseArea> areaList = iWmsBasicWarehouseAreaService.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, warehouseArea.getWmsBasicWarehouseId())
        );
        WmsBasicWarehouse warehouse = iWmsBasicWarehouseService.getById(warehouseArea.getWmsBasicWarehouseId());
        warehouse.setMaxCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacity())).map(WmsBasicWarehouseArea::getMaxCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setWarningCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacity())).map(WmsBasicWarehouseArea::getWarningCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMinCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacity())).map(WmsBasicWarehouseArea::getMinCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMaxCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacityAssist())).map(WmsBasicWarehouseArea::getMaxCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setWarningCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacityAssist())).map(WmsBasicWarehouseArea::getWarningCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMinCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacityAssist())).map(WmsBasicWarehouseArea::getMinCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        if ("Y".equals(warehouse.getIsUseArea())){
            iWmsBasicWarehouseService.updateById(warehouse);
        }
    }

    /**
     * 更新基准点
     * @param wmsBasicWarehouseAreaLocation
     */
    private void updateDatum(WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation) {
        // 基准点
        if ("1".equals(wmsBasicWarehouseAreaLocation.getIsDatum())) {
            List<WmsBasicWarehouseAreaLocation> list = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                    .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                    .eq(WmsBasicWarehouseAreaLocation::getIsDatum, "1"));
            for (WmsBasicWarehouseAreaLocation location : list) {
                location.setIsDatum("0");
                this.updateById(location);
            }
        }
        // 包装基准点
        if ("1".equals(wmsBasicWarehouseAreaLocation.getIsPackageDatum())) {
            List<WmsBasicWarehouseAreaLocation> list = this.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                    .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseAreaLocation.getWmsBasicWarehouseAreaId())
                    .eq(WmsBasicWarehouseAreaLocation::getIsPackageDatum, "1"));
            for (WmsBasicWarehouseAreaLocation location : list) {
                location.setIsPackageDatum("0");
                this.updateById(location);
            }
        }
    }
}
